﻿using WeifenLuo.WinFormsUI.Docking;
using Koala.Pro.CodeGenerator.UI.Common;
using Koala.Pro.CodeGenerator.UI.DatabaseModel.Schema;
using Koala.Pro.CodeGenerator.UI.Models;
using Koala.Pro.CodeGenerator.UI.Controls;
using Koala.Pro.CodeGenerator.UI.Common.EntityProject;
using Newtonsoft.Json.Linq;

namespace Koala.Pro.CodeGenerator.UI
{
    public partial class ToolWindow : DockContent
    {
        public ToolWindow()
        {
            InitializeComponent();

            LoadSchema(null);
        }

        public void FillTableList(string selectedDatabaseName)
        {
            new FillTablesCommand(this, Program.global.DbInstance, treeView, selectedDatabaseName).Execute();
        }

        public void LoadSchema(string databaseName)
        {
            var err = "无法加载数据库信息，你希望对数据库进行配置么？";
            DbInstanceInfo dbInstance = Program.global.DbInstance;
            ProgressWindow progressWindow = new ProgressWindow();
            LoadTablesDetails loadTablesDetails = new LoadTablesDetails(dbInstance, databaseName, progressWindow);
            ThreadPool.QueueUserWorkItem(LoadDbListThreaded, loadTablesDetails);
            progressWindow.ShowDialog();
        }

        private void LoadDbListThreaded(object? status)
        {
            LoadTablesDetails loadTablesDetails = status as LoadTablesDetails;
            try
            {
                loadTablesDetails.ProgressCallBack.Begin();
                Program.global.DbInstance = SchemaBuilder.CreateDatabaseSchema(loadTablesDetails.DbInstance, loadTablesDetails.ProgressCallBack, loadTablesDetails.DatabaseName);
                if (Program.global.DbInstance != null)
                {
                    if (InvokeRequired)
                    {
                        BeginInvoke(new Action(() =>
                        {
                            FillTableList(loadTablesDetails.DatabaseName);
                        }));
                    }
                    else
                    {
                        FillTableList(loadTablesDetails.DatabaseName);
                    }
                }
            }
            catch (Exception ex)
            {
                var err = $"无法加载数据库信息，你希望对数据库进行配置么？\n{ex.Message}";
                if (DialogResult.Yes == MessageUtil.ShowYesNoAndError(err))
                {
                    FrmConfigure form = new FrmConfigure();
                    var dialogResult = form.ShowDialog();
                    if (dialogResult == DialogResult.OK)
                    {
                        LoadSchema(null);
                    }
                }
            }
            finally
            {
                loadTablesDetails.ProgressCallBack.End();
            }
        }

        private void mainTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            int level = Program.global.GetNodeLevel(e.Node);
            switch (level)
            {
                case 1:
                    treeView.SelectedNode = e.Node;
                    e.Node.Expand();
                    break;
                case 2:

                    break;
                case 3:
                    DisplayEntity displayEntity = new DisplayEntity(e.Node.Tag.ToString(), e.Node.Parent.Parent.Text, e.Node.Text);
                    ThreadPool.QueueUserWorkItem(AnsyReceiveData, displayEntity);
                    break;
            }
        }

        private void AnsyReceiveData(object? param)
        {
            try
            {
                Invoke(BindTableInfo, param);
            }
            catch (Exception ex)
            {
                MessageUtil.ShowError(ex.Message);
            }
        }

        private void BindTableInfo(DisplayEntity entity)
        {
            DisplayInfo(entity.type, entity.database, entity.leaf);
        }

        private void DisplayInfo(string type, string database, string leaf)
        {
            switch (type)
            {
                case "table":
                    DisplayTableDetail(database, leaf);
                    break;
                case "view":
                    //DisplayOtherDetail(database, leaf, 0);
                    break;
                case "procedure":
                    //DisplayOtherDetail(database, leaf, 1);
                    break;
            }
        }

        private void DisplayTableDetail(string database, string tableName)
        {
            IDictionary<string, ColumnInfo> columnList = Program.global.DbInstance.DatabaseList[database].TableList[tableName].ListColumns();
            var form = (FrmTableInfo)Program.global.MainView.ShowContent(typeof(FrmTableInfo));
            form.DbName = database;
            form.TableName = tableName;
            form.ColumnList = columnList;
            treeView.Focus();
            try
            {
                string dbType = Program.global.AssemblyTypeShortName;
                string text = string.Empty;
                form.txtCodeEditor.Text = string.Empty;
                List<FileNameAndCode> createTableSql = DatabaseSqlManager.GetCreateTableSql(dbType, tableName, columnList.Values);
                foreach (FileNameAndCode item in createTableSql)
                {
                    text += item.Code;
                }
                FormatCodeHelper.FormatText(form.txtCodeEditor, FormatCodeHelper.TSQL, text);
            }
            catch (Exception ex)
            {
                MessageUtil.ShowError(ex.Message);
            }
        }

        private void mainTree_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Button == MouseButtons.Left && e.Clicks == 1 && e.Node.Tag.ToString() == "database")
            {
                //LoadSchema(e.Node.Text);
            }
        }

        private void mainTree_MouseDown(object sender, MouseEventArgs e)
        {
            if (e.Button != MouseButtons.Right)
            {
                return;
            }
            TreeNode nodeAt = treeView.GetNodeAt(e.X, e.Y);
            if (nodeAt != null)
            {
                treeView.SelectedNode = nodeAt;
                if (nodeAt.Tag.ToString() == "Tables" || nodeAt.Tag.ToString() == "table" || nodeAt.Tag.ToString() == "database")
                {
                    treeView.ContextMenuStrip = tableMenu;
                }
                else
                {
                    treeView.ContextMenuStrip = null;
                }
                if (nodeAt.Tag.ToString() == "table")
                {
                    ctxTable_Sql.Enabled = true;
                }
                else
                {
                    ctxTable_Sql.Enabled = false;
                }
            }
        }

        public string GetSelectedDatabaseName()
        {
            TreeNode selectedNode = treeView.SelectedNode;
            if (selectedNode == null)
            {
                return null;
            }
            string result = null;
            if (selectedNode.Tag.ToString() == "Tables")
            {
                result = selectedNode.Parent.Text;
            }
            else if (selectedNode.Tag.ToString() == "table")
            {
                result = selectedNode.Parent.Parent.Text;
            }
            else if (selectedNode.Tag.ToString() == "database")
            {
                result = selectedNode.Text;
            }
            return result;
        }

        public string GetSelectedTableName()
        {
            TreeNode selectedNode = treeView.SelectedNode;
            if (selectedNode == null)
            {
                return null;
            }
            string empty = string.Empty;
            if (selectedNode.Tag.ToString() == "table")
            {
                empty = selectedNode.Text;
            }
            return empty;
        }

        private void ctxTable_QueryAnalyzer_Click(object sender, EventArgs e)
        {
            Program.global.MainView.ShowContent(typeof(FrmQueryAnalyzer));
        }

        private void ctxTable_Quick_FieldEntity_Click(object sender, EventArgs e)
        {
            menu_Quick_FieldEntity_Click(null, null);
        }

        private void menu_Quick_FieldEntity_Click(object sender, EventArgs e)
        {
            try
            {
                var form = new FrmSelectTables();
                if (form.ShowDialog() != DialogResult.OK)
                {
                    return;
                }
                string assemblyTypeShortName = Program.global.AssemblyTypeShortName;
                var databaseInfo = Program.global.DbInstance.DatabaseList[GetSelectedDatabaseName()];
                var tableList = Program.global.SelectedTableNames;
                List<FileNameAndCode> list = SimpleEntityProject.ExecuteString(databaseInfo, tableList, null);
                foreach (FileNameAndCode item in list)
                {
                    var codeFrm = (FrmCode)Program.global.MainView.ShowContent(typeof(FrmCode), DockContentShowTypeEnum.New);
                    codeFrm.Text = item.FileName;
                    FormatCodeHelper.FormatText(codeFrm.txtCodeEditor, FormatCodeHelper.CSHARP, item.Code);
                }
            }
            catch (Exception ex)
            {
                MessageUtil.ShowError(ex.Message);
            }
        }

        private void ctxTable_Quick_SqlSugar_Click(object sender, EventArgs e)
        {
            try
            {
                var form = new FrmSelectTables();
                if (form.ShowDialog() != DialogResult.OK)
                {
                    return;
                }
                string assemblyTypeShortName = Program.global.AssemblyTypeShortName;
                var databaseInfo = Program.global.DbInstance.DatabaseList[GetSelectedDatabaseName()];
                var tableList = Program.global.SelectedTableNames;
                List<FileNameAndCode> list = SqlsugarEntityProject.ExecuteString(databaseInfo, tableList, null);
                foreach (FileNameAndCode item in list)
                {
                    var codeFrm = (FrmCode)Program.global.MainView.ShowContent(typeof(FrmCode), DockContentShowTypeEnum.New);
                    codeFrm.Text = item.FileName;
                    FormatCodeHelper.FormatText(codeFrm.txtCodeEditor, FormatCodeHelper.CSHARP, item.Code);
                }
            }
            catch (Exception ex)
            {
                MessageUtil.ShowError(ex.Message);
            }
        }

        private void ctxTable_TableAlias_Click(object sender, EventArgs e)
        {
            string selectedDatabaseName = GetSelectedDatabaseName();
            DatabaseInfo databaseInfo = Program.global.DbInstance.DatabaseList[selectedDatabaseName];
            if (databaseInfo.TableList == null || databaseInfo.TableList.Count <= 0)
            {
                databaseInfo.ListTables();
            }
            var setTableAliasForm = new FrmSetTableAlias();
            int num = databaseInfo.TableList.Count * 25;
            int num2 = setTableAliasForm.Size.Height;
            if (num + 60 > setTableAliasForm.Size.Height)
            {
                num2 = num + 60;
            }
            setTableAliasForm.Size = new Size(setTableAliasForm.Size.Width, num2);
            foreach (TableInfo value in databaseInfo.TableList.Values)
            {
                Label label = new Label();
                label.Height = 40;
                label.TextAlign = ContentAlignment.MiddleRight;
                label.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
                label.Text = value.Name.Name.ToString() + "：";
                TextBox textBox = new TextBox();
                textBox.Height = 40;
                textBox.Name = value.Name.Name.ToString();
                textBox.Text = value.Name.Alias.ToString();
                textBox.Tag = value.Name.Alias.ToString();
                textBox.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
                setTableAliasForm.tableLayoutPanel1.Controls.Add(label);
                setTableAliasForm.tableLayoutPanel1.Controls.Add(textBox);
            }
            if (DialogResult.OK == setTableAliasForm.ShowDialog() && setTableAliasForm.IsDirty)
            {
                //TableNameAliasInfo.TableNameAliasTable = null;
            }
        }

        private void ctxTable_CodeGen_SqlsugarWPF_Click(object sender, EventArgs e)
        {
            var form = (FrmUIGenerator)Program.global.MainView.ShowContent(typeof(FrmUIGenerator), DockContentShowTypeEnum.New);
        }
    }
}
